package com.habdqn.studentmanager.service.impl;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.math.BigDecimal;
import java.util.Date;
import java.util.List;

import javax.annotation.Resource;
import javax.transaction.Transactional;

import org.apache.log4j.Logger;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.habdqn.studentmanager.bean.Dictionary;
import com.habdqn.studentmanager.bean.Employment;
import com.habdqn.studentmanager.bean.Student;
import com.habdqn.studentmanager.bean.Teacher;
import com.habdqn.studentmanager.bean.condition.BigDecimalCondition;
import com.habdqn.studentmanager.bean.condition.DateCondition;
import com.habdqn.studentmanager.constant.DictType;
import com.habdqn.studentmanager.constant.LogType;
import com.habdqn.studentmanager.exception.StudentException;
import com.habdqn.studentmanager.mapper.EmploymentMapper;
import com.habdqn.studentmanager.service.DictionaryService;
import com.habdqn.studentmanager.service.EmploymentService;
import com.habdqn.studentmanager.service.StudentService;
import com.habdqn.studentmanager.service.TeacherService;
import com.habdqn.studentmanager.util.ConfigUtil;
import com.habdqn.studentmanager.util.DateUtil;
import com.habdqn.studentmanager.util.ExcelUtil;
import com.habdqn.studentmanager.util.ExcelUtil.Excel.Cell;
import com.habdqn.studentmanager.util.ExcelUtil.Excel.Row;
import com.habdqn.studentmanager.util.ProjectUtil;
import com.habdqn.studentmanager.util.SystemLogger;

@Service("employmentService")
public class EmploymentSerivceImpl implements EmploymentService {

	private static Logger logger = Logger.getLogger(EmploymentSerivceImpl.class);

	@Resource
	private SystemLogger systemLogger;

	@Resource
	private EmploymentMapper employmentMapper;

	@Resource
	private DictionaryService dicService;

	@Resource
	private StudentService studentService;

	@Resource
	private TeacherService teacherService;

	@Override
	public void add(Employment bean) {
		try {
			employmentMapper.insert(bean);
		}
		catch (DuplicateKeyException e) {
			logger.debug("就业信息重复");
			throw new StudentException("就业信息重复", e);
		}
		catch (Exception e) {
			logger.error("添加就业信息失败");
			throw new StudentException("添加就业信息失败", e);
		}
		systemLogger.record(LogType.AddType, "添加\"" + bean.getStudent().getName() + "\"就业信息,编号:" + bean.getId());
	}

	@Override
	public PageInfo<Employment> findList(Student bean, BigDecimalCondition salary, DateCondition employmentDate,
	        Integer pageNum, Integer pageSize) {
		PageInfo<Employment> page = null;
		PageHelper.startPage(pageNum, pageSize);
		try {
			List<Employment> list = employmentMapper.findList(bean, salary, employmentDate);
			page = new PageInfo<Employment>(list);
		}
		catch (Exception e) {
			logger.error("查询就业信息失败", e);
			throw new StudentException("查询就业信息失败", e);
		}
		return page;
	}

	@Override
	public void update(Employment bean) {
		try {
			employmentMapper.update(bean);
			logger.debug("更新就业信息成功");
		}
		catch (Exception e) {
			logger.error("更新失败", e);
			throw new StudentException("更新失败", e);
		}
		systemLogger.record(LogType.UpdateType, "更新\"" + bean.getStudent().getName() + "\"就业信息,编号:" + bean.getId());

	}

	@Override
	public int delte(Integer id) {
		int i = -1;
		try {
			i = employmentMapper.delete(id);
		}
		catch (Exception e) {
			logger.error("删除就业信息失败", e);
			throw new StudentException("删除就业信息失败", e);
		}
		logger.debug("删除就业信息成功");
		systemLogger.record(LogType.DelType, "删除就业信息，编号：" + id);
		return i;
	}

	@Override
	public Employment find(Employment bean) {
		try {
			bean = employmentMapper.find(bean);
			return bean;
		}
		catch (Exception e) {
			logger.error("查找就业信息失败", e);
			throw new StudentException("查找就业信息失败", e);
		}

	}

	@Override
	public void export(Student bean, BigDecimalCondition salary, DateCondition employmentDate, OutputStream out) {
		// 获取模板文件的路径
		String path = ProjectUtil.getRealPath() + ConfigUtil.getKey("excelDemoPath") + File.separator
		        + "employment-demo.xlsx";
		PageInfo<Employment> page = findList(bean, salary, employmentDate, 1, 0);
		try (InputStream is = new FileInputStream(path)) {
			ExcelUtil.init(is).sheetAt(0).rowAt(2).export(page.getList(), out, (Employment e, Row row) -> {
				row.createCell(0).setValue(e.getStudent().getId());
				row.createCell(1).setValue(e.getStudent().getName());
				row.createCell(2).setValue(String.valueOf(e.getTeacher().getId()));
				row.createCell(3).setValue(e.getTeacher().getName());
				row.createCell(4).setValue(e.getEmploymentCity());
				row.createCell(5).setValue(e.getEmploymentType().getName());
				row.createCell(6).setValue(String.valueOf(e.getReferNum()));
				row.createCell(7).setValue(DateUtil.format(e.getEmploymentDate(), DateUtil.FormatStr10));
				row.createCell(8).setValue(e.getCompanyName());
				if (null != e.getCompanyType()) {
					row.createCell(9).setValue(e.getCompanyType().getName());
				}
				if (null != e.getCompanyScale()) {
					row.createCell(10).setValue(e.getCompanyScale().getName());
				}
				row.createCell(11).setValue(e.getJob());
				row.createCell(12).setValue("1".equals(e.getIsCorrespond()) ? "是" : "否");
				row.createCell(13).setValue(String.valueOf(e.getSalary()));
				row.createCell(14).setValue(e.getExt3());
				row.createCell(15).setValue(e.getExt1());
				row.createCell(16).setValue(e.getExt2());
				row.createCell(17).setValue(e.getRemarks());
			}).close();
		}
		catch (FileNotFoundException e) {
			logger.error("模版文件不存在", e);
			throw new StudentException("模版文件不存在", e);
		}
		catch (IOException e) {
			logger.error("操作文件失败", e);
			throw new StudentException("操作文件失败", e);
		}
	}

	@Override
	@Transactional
	public void importEmp(InputStream is) {
		ExcelUtil.init(is).sheetAt(0).rowAt(2).accept((Row row) -> {
			// 从1开始的行号
			int rowNum = row.getRowAt() + 1;

			try {
				accept(row);
			}
			catch (RuntimeException e) {
				logger.debug("导入失败", e);
				throw new StudentException("第" + rowNum + "行:" + e.getMessage(), e);
			}
		}).close();

	}

	/**
	 * 字符串转为Integer
	 * 
	 * @param str
	 * @return
	 */
	private Integer strToInt(String str) throws NumberFormatException {
		if (StringUtils.isEmpty(str)) {
			return null;
		}
		if (str.indexOf(".") != -1) {
			return Integer.valueOf(str.substring(0, str.indexOf(".")));
		}
		return Integer.valueOf(str);
	}

	private void accept(Row row) {
		Employment bean = new Employment();
		Student student = new Student();
		student.setId(row.getCell(0).getValue());
		student = studentService.find(student);
		if (student == null) {
			throw new StudentException("学员id错误");
		}
		bean.setStudent(student);
		Teacher teacher = new Teacher();
		String id = row.getCell(2).getValue();
		if (StringUtils.isEmpty(id)) {
			throw new StudentException("就业老师id为空");
		}
		teacher.setId(strToInt(id));
		teacher = teacherService.find(teacher);
		if (null == teacher) {
			throw new StudentException("就业老师id错误");
		}
		bean.setTeacher(teacher);
		String employmentCity = row.getCell(3).getValue();
		if (StringUtils.isEmpty(employmentCity)) {
			throw new StudentException("就业城市为空");
		}
		bean.setEmploymentCity(employmentCity);
		Dictionary employmentType = new Dictionary();
		try {
			employmentType
			        .setValue(dicService.findValue(DictType.EmploymentType.toInteger(), row.getCell(4).getValue()));
		}
		catch (RuntimeException e) {
			throw new StudentException("就业类型错误", e);
		}
		bean.setEmploymentType(employmentType);
		try {
			bean.setReferNum(strToInt(row.getCell(5).getValue()));
		}
		catch (NumberFormatException e) {
			throw new StudentException("推荐次数填写错误", e);
		}
		Date employmentDate = DateUtil.parseDate(row.getCell(6).getValue(), DateUtil.FormatStr10);
		if (employmentDate == null) {
			throw new StudentException("就业日期不能为空且格式要正确");
		}
		bean.setEmploymentDate(employmentDate);
		String companyName = row.getCell(7).getValue();
		if (StringUtils.isEmpty(companyName)) {
			throw new StudentException("公司名称为空");
		}
		bean.setCompanyName(companyName);
		if (!StringUtils.isEmpty(row.getCell(8).getValue())) {
			Dictionary companyType = new Dictionary();
			try {
				companyType.setValue(dicService.findValue(DictType.CompanyType.toInteger(), row.getCell(8).getValue()));
			}
			catch (Exception e) {
				throw new StudentException("公司类型填写错误", e);
			}
			bean.setCompanyType(companyType);
		}
		if (!StringUtils.isEmpty(row.getCell(9).getValue())) {

			Dictionary companyScale = new Dictionary();
			try {
				companyScale
				        .setValue(dicService.findValue(DictType.CompanyScale.toInteger(), row.getCell(9).getValue()));
			}
			catch (Exception e) {
				throw new StudentException("公司规模填写", e);
			}
			bean.setCompanyScale(companyScale);
		}
		String job = row.getCell(10).getValue();
		if (StringUtils.isEmpty(job)) {
			throw new StudentException("工作职位为空");
		}
		bean.setJob(job);
		String isCorrespond = row.getCell(11).getValue();
		if ("是".equals(isCorrespond)) {
			bean.setIsCorrespond("1");
		}
		else if ("否".equals(isCorrespond)) {
			bean.setIsCorrespond("0");
		}
		else {
			throw new StudentException("是否对口就业错误");
		}
		try {
			bean.setSalary(new BigDecimal(row.getCell(12).getValue()));
		}
		catch (NumberFormatException e) {
			throw new StudentException("转正薪资填写错误", e);
		}
		String ext3 = row.getCell(13).getValue();
		if (StringUtils.isEmpty(ext3)) {
			throw new StudentException("薪资福利不能为空");
		}
		bean.setExt3(ext3);
		bean.setExt1(row.getCell(14).getValue());
		bean.setExt2(row.getCell(15).getValue());
		bean.setRemarks(getCellValue(row.getCell(16)));
		add(bean);
	}

	/**
	 * 获取可能为null的cell中的值
	 * 
	 * @param cell
	 * @return
	 */
	private String getCellValue(Cell cell) {
		if (null != cell) {
			return cell.getValue();
		}
		return null;
	}

	@Override
	public int realDel(Integer id) {
		int i = -1;
		try {
			i = employmentMapper.realDel(id);
		}
		catch (Exception e) {
			logger.error("删除就业信息失败", e);
			throw new StudentException("删除就业信息失败", e);
		}
		logger.debug("删除就业信息成功");
		systemLogger.record(LogType.DelType, "删除就业信息，编号：" + id);
		return i;
	}

}
